shopr

Check-in [0299666a71]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Item name editing
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256:0299666a717d877b5a00a84c05ecb82bdf333dbf4163c6ad77362d8b1ef225d1
User & Date: vandys 2019-06-24 20:42:23
Context
2019-06-25
16:54
Add favicon check-in: 5676483ab6 user: vandys tags: trunk
2019-06-24
20:42
Item name editing check-in: 0299666a71 user: vandys tags: trunk
2019-06-23
22:32
Get "+RGY" (show all colors) working. check-in: 84801ee99c user: vandys tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to items.py.

61
62
63
64
65
66
67
68

69
70
71
72
73
74
75
	sema.acquire()
	# Resume here after next_gen()

    # A JSON wrap-up of our content
    def for_json(self):
	items = []
	res = {"name": self.name, "items": items, "gen": self.gen}
	for i in sorted(self.items.itervalues(), key=lambda _i: _i.name):

	    # Don't share deleted
	    if i.deleted():
		continue
	    items.append(i.for_json())
	return res

    # Update idx for the given item







|
>







61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
	sema.acquire()
	# Resume here after next_gen()

    # A JSON wrap-up of our content
    def for_json(self):
	items = []
	res = {"name": self.name, "items": items, "gen": self.gen}
	for i in sorted(self.items.itervalues(),
		key=lambda _i: _i.name.lower()):
	    # Don't share deleted
	    if i.deleted():
		continue
	    items.append(i.for_json())
	return res

    # Update idx for the given item

Changes to js/shopr.js.

23
24
25
26
27
28
29



30
31
32
33
34
35
36
...
158
159
160
161
162
163
164

165
166
167
168
169
170
171
...
316
317
318
319
320
321
322
323


324
325
326
327
328
329
330
...
475
476
477
478
479
480
481
























482
483
484
485
486
487
488
...
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511


















512
513
514
515
516
517
518
// Set of indices currently being displayed
// Initial state, show all
const cur_idxs = new Set([0, 1, 2]);

// Map from the Element ID to its Item ID in the DB
const iids = {};




//
// These toggle the filtering based on color
//
// Each toggles between darker version of color (showing it)
//  and its lighter counterpart.
//
function filtR() {
................................................................................

// Long hold; menu on current element
function hold_item(e) {
    if (!e.id.startsWith("item")) {
	return false;
    }
    itname.value = e.innerText;

    setcur(scritem);
}

// Click an item, probably switch the index of the item
function click_item(e) {
    // Tap on already selected item index?
    if (e.textContent) {
................................................................................
	    }
	    nidx += 1;
	    oidx += 1;
	    continue;
	}

	// Inserted cell?
	if (i1.name < i2.name) {


	    e2.style.background = "green";
	    changed = true;
	    nidx += 1;
	    continue;
	}

	// Deleted cell
................................................................................
	".json" + authURL;

    // Requesting URL, including authentication
    req.open("POST", url);
    const op = {"op": "add", "name": ifv};
    req.send(JSON.stringify(op));
}

























// Remove an item
//
// It's the one which was long held to get this menu
function del_iname() {
    // Name to iid
    let iid = null;
................................................................................
	}
    }
    if (iid == null) {
	// WTF?
	return;
    }

    // Construct URL; our list, authen
    let url = "/l/" + encodeURIComponent(cur_list) +
	".json" + authURL;

    // PUT w. authen, op == "delete this iid"
    const req = new XMLHttpRequest();
    req.open("PUT", url);
    const op = {"op": "del", "iid": iid};
    req.send(JSON.stringify(op));

    // Leave menu for item (which should be Going Away)
    cancel_scritem();
}



















// Choose a list
function sel_list(e) {
    cur_list = e.currentTarget.textContent;
    localStorage.setItem("curlist", cur_list);
    cur_names = null;
    paint_list();







>
>
>







 







>







 







|
>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|
|
<
<
<
<
<
<
<




>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
...
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
...
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
...
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
...
522
523
524
525
526
527
528
529
530







531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
// Set of indices currently being displayed
// Initial state, show all
const cur_idxs = new Set([0, 1, 2]);

// Map from the Element ID to its Item ID in the DB
const iids = {};

// When itname is naming an item to edit, this is its Item ID
var itname_iid = null;

//
// These toggle the filtering based on color
//
// Each toggles between darker version of color (showing it)
//  and its lighter counterpart.
//
function filtR() {
................................................................................

// Long hold; menu on current element
function hold_item(e) {
    if (!e.id.startsWith("item")) {
	return false;
    }
    itname.value = e.innerText;
    itname_iid = iids[e.id];
    setcur(scritem);
}

// Click an item, probably switch the index of the item
function click_item(e) {
    // Tap on already selected item index?
    if (e.textContent) {
................................................................................
	    }
	    nidx += 1;
	    oidx += 1;
	    continue;
	}

	// Inserted cell?
	// (Our server orders case insenstive, so to track their order
	//  we need to honor that here.)
	if (i1.name.toLowerCase() < i2.name.toLowerCase()) {
	    e2.style.background = "green";
	    changed = true;
	    nidx += 1;
	    continue;
	}

	// Deleted cell
................................................................................
	".json" + authURL;

    // Requesting URL, including authentication
    req.open("POST", url);
    const op = {"op": "add", "name": ifv};
    req.send(JSON.stringify(op));
}

// Do a PUT op with authentication to our current list
function xhr_put(msg, fn) {
    // Construct URL; our list, authen
    const url = "/l/" + encodeURIComponent(cur_list) +
	".json" + authURL;

    // PUT w. authen, op == "delete this iid"
    const req = new XMLHttpRequest();
    req.open("PUT", url);

    // Optional callback
    if (fn != null) {
	req.onreadystatechange = () => {
	    if (req.readyState != 4) {
		return;
	    }

	    fn(req.status, req.responseText);
	    return;
	}
    }
    req.send(JSON.stringify(msg));
}

// Remove an item
//
// It's the one which was long held to get this menu
function del_iname() {
    // Name to iid
    let iid = null;
................................................................................
	}
    }
    if (iid == null) {
	// WTF?
	return;
    }

    // Request delete
    xhr_put({op: "del", iid: iid}, null);








    // Leave menu for item (which should be Going Away)
    cancel_scritem();
}

// Change item's name
function new_iname() {
    if (!itname.value) {
	alert("Please enter the new item name");
	return false;
    }
    const callb = (code, txt) => {
	if (code != 200) {
	    alert("Rename failed: " + txt);
	} else {
	    // Go back to main display
	    ifilter.value = "";
	    cancel_scritem();
	}
    };
    xhr_put({op: "rename", iid: itname_iid, name: itname.value}, callb);
}

// Choose a list
function sel_list(e) {
    cur_list = e.currentTarget.textContent;
    localStorage.setItem("curlist", cur_list);
    cur_names = null;
    paint_list();

Changes to put.py.

40
41
42
43
44
45
46



47
48
49
50
51
52
53
..
57
58
59
60
61
62
63






















64
65
	    d = json.loads(buf)
	    op = str(d["op"])
	    if op == "idx":
		iid = int(d["iid"])
		col = int(d["col"])
	    elif op == "del":
		iid = int(d["iid"])



	    else:
		return True,self.send_error(400, "No such op")
	except:
	    return True,self.send_error(400, "Malformed JSON")

	# Update item, and churn the list
	if op == "idx":
................................................................................

	# Delete item from this list
	if op == "del":
	    if l.del_item(iid):
		return True,self.send_json({"ok": True})
	    return True,self.send_error(400, "Bad item")























	# "Can't Happen"
	return True,self.send_error(500)







>
>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
..
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
	    d = json.loads(buf)
	    op = str(d["op"])
	    if op == "idx":
		iid = int(d["iid"])
		col = int(d["col"])
	    elif op == "del":
		iid = int(d["iid"])
	    elif op == "rename":
		iid = int(d["iid"])
		name = str(d["name"])
	    else:
		return True,self.send_error(400, "No such op")
	except:
	    return True,self.send_error(400, "Malformed JSON")

	# Update item, and churn the list
	if op == "idx":
................................................................................

	# Delete item from this list
	if op == "del":
	    if l.del_item(iid):
		return True,self.send_json({"ok": True})
	    return True,self.send_error(400, "Bad item")

	# Change item's name
	if op == "rename":
	    i = l.items.get(iid)
	    if i is None:
		return True,self.send_error(400, "No such item")

	    # Just adjusting capitalization.  Since all comparisons
	    #  are case insensitive, this is always OK.
	    nl = name.lower()
	    if i.name.lower() != nl:

		# Can't name on top of another element
		for i2 in l.items.itervalues():
		    if i2.name.lower() == nl:
			return True,self.send_error(409, "Name exists")

	    # Our users see this change
	    i.name = name
	    l.next_gen()

	    return True,self.send_json({"ok": True})

	# "Can't Happen"
	return True,self.send_error(500)